\documentclass[a4paper,10pt]{article}

\usepackage{graphicx}
\usepackage{amsmath}
\usepackage[latin1]{inputenc}
\usepackage[spanish]{babel}

\title{ \textbf{ 6620. Organizaci\'on de Computadoras\\
Trabajo Pr\'actico 0: \\
Infraestructura B\'asica}}

\author{	Romeo, Mauro, \textit{Padr\'on Nro. 89368} \\
            	\texttt{ mauropromeo@hotmail.com } \\[2.5ex]
            	Arg\"uello, Osiris, \textit{Padr\'on Nro. 83.062} \\
            	\texttt{ osirisarguello@gmail.com } \\[2.5ex]
		Constantino, Guillermo, \textit{Padr\'on Nro. 89776} \\
		\texttt{ guilleconstantino@gmail.com } \\[2.5ex]
            	\normalsize{1er. Cuatrimestre de 2014} \\
            	\normalsize{66.20 Organizaci\'on de Computadoras  $-$ Pr\'atica Jueves} \\
            	\normalsize{Facultad de Ingenier\'ia, Universidad de Buenos Aires} \\
       }

\date{}

\begin{document}
\maketitle
\thispagestyle{empty}  % quita el nmero en la primer pagina


\begin{abstract}
El presente trabajo tiene como objetivo familiarizarse con las herramientas de software que ser\'an usadas en los siguientes trabajos, implementando un programa (y su correspondiente documentaci\'on) que resuelva el problema  piloto planteado, una implementaci\'on del algoritmo de codificaci\'on \textit{BASE64} en lenguaje C. A su vez, se utilizar\'a el programa GXemul para simular un entorno de desarrollo en una m\'aquina MIPS, a fin de obtener el c\'odigo en Assembly MIPS32 de la implementaci\'on realizada.


\end{abstract}
\pagebreak

\setcounter{page}{2}
\section{Introducci\'on}
Al comenzar a utilizar nuevas herramientas, en cualquier \'ambito, es necesaria una breve introducci\'on al funcionamiento de las mismas: tener una noci\'on de las prestaciones que ofrecen, asi tambi\'en como de sus limitaciones.\\
Como primer objetivo en la materia, nos proponemos adentrarnos en el funcionamiento del emulador GXemul. Nuestra meta ser\'a emular una plataforma MIPS DECstation 5000/200 (ejecutando un sistema operativo NetBSD), para poder desde all\'i desarrollar programas en lenguaje C. Estos ser\'an compilados y ejecutados haciendo uso de la herramienta GCC (GNU Compiler Collection), mediante el cual tambi\'en ser\'a posible obtener, a posteriori, el c\'odigo MIPS32 del programa.\\
Una vez cumplido este objetivo, aprenderemos los rudimientos de \LaTeX{} para generar la documentaci\'on relevante al trabajo pr\'actico.

\section{Programa a implementar}
\textit{Base 64} es un sistema de numeraci\'on posicional que usa 64 como base. Es la mayor potencia de dos que puede ser representada usando \'unicamente los caracteres imprimibles de ASCII. Esto ha propiciado su uso para codificaci\'on de correos electr\'onicos, PGP y otras aplicaciones. Todas las variantes famosas que se conocen con el nombre de \textit{Base64} usan el rango de caracteres A-Z, a-z y 0-9 en este orden para los primeros 62 d\'igitos, pero los s\'imbolos escogidos para los \'ultimos dos d\'igitos var\'ian considerablemente de unas a otras.

\section{Desarrollo del Trabajo Pr\'actico}

\subsection{Consideraciones de Dise\~no}
Para este programa hemos decidido que si al decodificar, el programa encuentra algun caracter que no pertenece a los del alfabeto predeterminado, se informar\'a con un mensaje al usuario y se finalizar\'a la ejecuci\'on.
Por otro lado, hemos establecido que la acci\'on por default que realiza el programa, si no se indica ninguna, ser\'a realizar una codificaci\'on.

\subsection{Explicaci\'on de la Implementaci\'on}
Las principales funciones y estructuras en nuestra implementaci\'on son las siguientes:

\subsubsection{main}
Esta funci\'on se encarga de procesar las opciones ingresadas por l\'inea de comando e invocar a las funciones \textit{encode} o \textit{decode} seg\'un lo ingresado.

\subsubsection{encode}
Esta funci\'on tiene como objetivo leer la entrada (sea un archivo o stdin), tomar 3 caracteres e invocar a la funci\'on \textit{doEncode}. El resultado de la codificaci\'on es luego escrito en el archivo de salida.

\subsubsection{decode}
Esta funci\'on es an\'aloga a la anterior, pero toma 4 caracteres de la entrada e invoca a la funci\'on \textit{doDecode} y el resultado es escrito en la salida (un archivo o stdout).

\subsubsection{doEncode}
Esta funci\'on es la encargada de tomar los 3 caracteres como 24 bits y operarlos para convertirlos en 4 bytes, que luego se mapearan al alfabeto de nuestra implementaci\'on de \textit{Base64} y estos seran los que se devolveran como resultado. 
Si la entrada no contaba con 3 caracteres, en esta funci\'on se agrega el padding necesario.

\subsubsection{doDecode}
Esta funci\'on se encarga de tomar los 4 caracteres leidos, reconvertirlos al numero correspondiente usando el alfabeto (tomando en cuenta el posible padding agregado) y operarlo para volver a obtener la entrada original.


\section{Generaci\'on de ejecutables y c\'odigo assembly}
Para generar el ejecutable del programa, debe correrse la siguiente sentencia en una terminal:

\begin{verbatim}
$ gcc -Wall -o tp0 tp0.c
\end{verbatim}

Para generar el c\'odigo MIPS32, debe ejecutarse lo siguiente:
\begin{verbatim}
$ gcc -Wall -S -mrnames tp0.c
\end{verbatim}

N\'otese que para ambos casos se han activado todos los mensajes de 'Warning' (-Wall). Adem\'as, para el caso de MIPS, se han habilitado otras dos banderas: '-S' que detiene al compilador luego de generar el assembly y '-mrnames' que tiene como objetivo generar la salida utilizando los nombres de los registros en vez de los n\'umeros de registros.
\pagebreak

\section{Corridas de prueba}

En esta secci\'on se presentan algunas de las distintas corridas que se realizaron para probar el funcionamiento del trabajo pr\'actico.\\
\\

Mostramos el menu de ayuda:
\begin{center}
\includegraphics[scale=0.60]{ayuda.png}
\end{center}

Codificamos y decodificamos la cadena "foo" para ver si nos devuelve la misma cadena:
\begin{center}
\includegraphics[scale=0.50]{foo.png}
\end{center}

Se observa que efectivamente nos devuelve la cadena que esperabamos.

Generemamos un archivo vacio cero.txt. Lo codificamos y guardamos en cero64.txt, y vemos que el archivo tambien esta vacio (0 bytes):
\begin{center}
\includegraphics[scale=0.50]{cero64.png}
\end{center}

Para mostrar el uso del padding codificamos el caracter \textit{"M"} solo:
\begin{center}
\includegraphics[scale=0.60]{m_encode.png}
\end{center}

Se agregan \textit{"0"} como padding para llegar a los 3 bytes y poder codificar. Los \textit{"0"} son codificados como \textit{=}.

De la misma manera decodificamos la cadena \textit{"TQ=="} y observamos que obtenemos el caracter \textit{"M"}:
\begin{center}
\includegraphics[scale=0.50]{m_decode.png}
\end{center}

Codificamos la cadena \textit{"Man"} y obtenemos la cadena \textit{"TFWu"} y luego decodificamos la cadena \textit{"TFWu"} y obtenemos la cadena original \textit{"Man"}:
\begin{center}
\includegraphics[scale=0.50]{man.png}
\end{center}

Se genera un archivo binario random de 1024 bytes y se lo guarda en un archivo \textit{random1024}, se lo codifica y se guarda la salida en \textit{random1024-64}. Luego se decodifica este ultimo archivo y se guarda la salida en \textit{random1024-comparar}. Se compara \textit{random1024} con \textit{random1024-comparar} con el comando \textbf{diff}. Tendria que dar como resultado que los archivos son iguales:
\begin{center}
\includegraphics[scale=0.50]{random.png}
\end{center}

Se observa que los dos archivos son iguales.

Se crea un archivo de texto \textit{Woman.txt} con la cadena \textit{"Woman"}, se lo codifica y se guarda el resultado en \textit{Woman-64.txt}. Se decodifica el archivo \textit{Woman-64.txt} y se lo guarda en \textit{Woman-64-decodificado.txt} y se observa que el archivo contiene la cadena \textit{"Woman"}:
\begin{center}
\includegraphics[scale=0.50]{woman.png}
\end{center}

Se corrobora utilizando el comando \textbf{diff}, y se ve que los archivos son iguales.
\pagebreak

\section{C\'odigo fuente C y MIPS32}

El c\'odigo MIPS32 que fue generado en el trabajo pr\'actico ha sido incluido en el CD entregado junto al presente informe.

\begin{verbatim}
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <err.h>


#define ENCODE_ACTION	1
#define DECODE_ACTION	2
#define DEFAULT_ACTION	1

#define FILE_BUFFER     2048

void usage(char* pgname)
{
	fprintf(stdout,"Usage:\n");
	fprintf(stdout,"%s -h\n",pgname);
	fprintf(stdout,"%s -V\n",pgname);
	fprintf(stdout,"%s [options]\n",pgname);

	fprintf(stdout,"Options:\n");
	fprintf(stdout,"%s -V, --version\t\t\tPrint version and quit.\n",pgname);		
	fprintf(stdout,"%s -h, --help\t\t\tPrint this information.\n",pgname);

	fprintf(stdout,"%s -i, --input\t\t\tLocation of the input file.\n",pgname);
	fprintf(stdout,"%s -o, --output\t\t\tLocation of the output file.\n",pgname);
	fprintf(stdout,"%s -e, --encode\t\t\tEncode file.\n",pgname);
	fprintf(stdout,"%s -d, --decode\t\t\tDecode file.\n",pgname);

	fprintf(stdout,"Examples:\n");
 
	fprintf(stdout,"%s -e -i input.txt -o output.txt\n",pgname);
	fprintf(stdout,"%s --decode -i output.txt -o output2.txt \n",pgname);
	
}

int doDecode(int source[], char decoded[], int amount)
{
	int i,padding,mapped[4];
	padding=0;

	for(i=0;i<4;i++){
		if(source[i]>=65 && source[i]<=90 ){
			mapped[i] = (source[i]-65);
		} else if(source[i] >= 97 && source[i] <= 122 ) {
			mapped[i] = (source[i]-97+26);			
		} else if(source[i]>=48 && source[i]<=57){
			mapped[i] = (source[i]-48+52);	
		} else if(source[i]==43){
			mapped[i] = 62;//'+'
		} else if(source[i]==47){
			mapped[i] = 63;//'/'
		} else if(source[i]==61 && (i==2)){
			if(source[i+1]!=61){
				//error si el tercer byte es padding, el cuarto tiene que serlo
				fprintf(stderr, "Error de padding, si el tercer caracter es '=', el cuerto debe serlo.\n");
				return -1;
			}
			padding++;		
		} else if(source[i]==61 && (i==3)){
			padding++;		
		} else {
			fprintf(stderr, "Caracter invalido (ASCII %d) %c\n", source[i], source[i]);
			return -1;
		}
	}

	// seteo todo temp en 0
	for(i=0; i < amount; i++){ 
		decoded[i]=0;
	}
	
	decoded[0] = mapped[0] << 2;
	decoded[0] |= mapped[1] >> 4;

	decoded[1] = mapped[1] << 4;
	decoded[1] |= mapped[2] >> 2;

	//posiciono los ultimos 4 bits de source[1] en las posiciones 2, 3, 4 y 5 de encoded[2]
	decoded[2] = (mapped[2] << 6); 
	decoded[2] |= mapped[3];
	
	
	return 3-padding;
}


int doEncode(int source[], char encoded[], int amount)
{
	int i, temp[4];

	// seteo todo temp en 0
	for(i=0; i < amount; i++){ 
		temp[i]=0;
	}
	// agrego 0 a la derecha
	for(i=amount; i<3; i++){source[i]=0;}
	
	temp[0] = source[0] >> 2;
	temp[0] &= 63;

	//posiciono los dos ultimos bits de source[0] en bits 2 y 3 de encoded[]
	temp[1] = 63 & (source[0] << 4);
	//copio los primeros 4 bits de source[2] en los ultimos lugares de encoded[1]
	temp[1] |= (63 & (source[1] >> 4));

	//posiciono los ultimos 4 bits de source[1] en las posiciones 2, 3, 4 y 5 de encoded[2]
	temp[2] = 63 & (source[1] << 2); 
	temp[2] |= 63 & (source[2] >> 6);


	temp[3] = 63 & source[2];//elimino los dos bit mas significativos y copio el resto como ultimo encoded[3]

	// mapeo los valores
	for(i=0;i<4;i++){
		if(temp[i]<=25 ){
			encoded[i] = (temp[i]+65);
		} else if(temp[i] <= 51) {
			encoded[i] = (temp[i]+97-26);			
		} else if(temp[i]<=61){
			encoded[i] = (temp[i]+48-52);	
		} else if(temp[i]==62){
			encoded[i] = 43;//'+'
		} else if(temp[i]==63){
			encoded[i] = 47;//'/'
		}
	}
	
	//padding
	if(amount==1){
		encoded[2]='=';
		encoded[3]='=';
	} else if(amount==2){
		encoded[3]='=';	
	}

	return 3;
}


int encode(int fdin,int fdout)
{
	
    FILE *fpout  = {0};

	if(fdout==1){
		fpout = stdout;
	} else {

		fpout = fdopen(fdout,"wb");

		if (fpout == 0) {
		    fprintf(stderr, "Error - Cannot open output stream %d\n", fdout);
		    fprintf(stderr, "Program will close unexpectedly\n");
		    exit(-1);
		}
	}

	
	int buffer[3] = {0};  /* initialized to zeroes */
	char bufferEncoded[3] = {0};
    int i, rc;

    FILE *fp = fdopen(fdin, "rb");
 
    if (fp == NULL) {
        perror("Failed to open input");
        return 1;
    }
	
	 
	while(rc != EOF){
		// leo 3 bytes
    	for (i = 0; i < 3 && (rc = getc(fp)) != EOF ; buffer[i++] = rc) {}
		if(i>0){

			doEncode(buffer, bufferEncoded, i);
			
			fwrite(bufferEncoded,1,4,fpout);						
			
		}		

	}
	
	
    // Cerramos los streams
    fclose(fpout);
    close(fdout);
    close(fdin);
	
	return 0;
}

int decode(int fdin,int fdout)
{
	
    FILE *fpout  = {0};
	
	if(fdout==1){
		fpout = stdout;
	} else {

		fpout = fdopen(fdout,"wb");

		if (fpout == 0) {
		    fprintf(stderr, "Error - Cannot open output stream %d\n", fdout);
		    fprintf(stderr, "Program will close unexpectedly\n");
		    exit(-1);
		}
	}
	
	int buffer[4] = {0};  /* initialized to zeroes */
	char bufferDecoded[4] = {0};
    int i, rc;

    FILE *fp = fdopen(fdin, "rb");
 
    if (fp == NULL) {
        perror("Failed to open input");
        return 1;
    }
 
	while(rc != EOF){
		// leo 4 bytes
		i=0;
	 	
    	for (i = 0; i < 4 && (rc = getc(fp)) != EOF; buffer[i++] = rc) {}

		if(i>0){
			int a = doDecode(buffer, bufferDecoded, i);

			if(a==-1){
			    fclose(fpout);
			    close(fdout);
				close(fdin);
				exit(1);
			}

			if(a==-1){
				// caracter invalido, poner stderr y terminar ejecucion	
				return -1;
			}

			for(i=0;i<a;i++){
				putc(bufferDecoded[i], fpout);
			}
		}	
	}
	
	
    // Cerramos los streams
    fclose(fpout);
    close(fdout);
    close(fdin);
	
	return 0;
}

int main(int argc, char *argv[])
{
    int fdin=0;
    int fdout=1;
    int ch;

	static struct option longopts[] = {
             { "version", no_argument, NULL, 'V' },
             { "help", no_argument, NULL, 'h' },
             { "encode", no_argument, NULL, 'e' },
             { "decode", no_argument, NULL, 'd' },
             { "input", required_argument, NULL, 'i' },
             { "output", required_argument, NULL, 'o' },
	         { NULL, 0, NULL, 0 }
     };
	
    int action = DEFAULT_ACTION;

    while ((ch = getopt_long(argc, argv, "o:i:edVh", longopts, NULL)) != -1)
	{
         switch (ch) {
			case 'o': 
				if (*optarg!='-' && ((fdout = open(optarg, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)) {
					fprintf(stderr, "unable to open %s\n", optarg);
		            usage(argv[0]);
					exit(1);
				}
				break;
			case 'i': 
				if (*optarg!='-' && ((fdin = open(optarg, O_RDONLY, 0)) == -1)) {
					fprintf(stderr, "unable to open %s\n", optarg);
		            usage(argv[0]);
					exit(1);
                }
                break;
			case 'e':
				action = ENCODE_ACTION;
				break;
			case 'd':
				action = DECODE_ACTION;
				break;
            case 'h': 
				usage(argv[0]);
            	exit(0);	
      	    	break;
			case 'V':
				printf("-- TP0 --\n");
				printf("Organizaci\on de Computadoras - 66.20\n");
				printf("Version 1.0\n");
				exit(0);
      	    	break;	     
            default:
            	usage(argv[0]);
				exit(0);
				break;
         }

	}

	if(action ==  ENCODE_ACTION){
		return encode(fdin, fdout);
	}
	
	return decode(fdin, fdout);
}

\end{verbatim}
\pagebreak

\section{Conclusiones}
El trabajo pr\'activo motivo de este informe ha presentado al equipo diversos desaf\'ios. En primer lugar cabe mencionar la adaptaci\'on a un ambiente basado en GNU/Linux, no dominado por todos sus integrantes en igual manera. Tambi\'en es destacable la dificultad inicial que trajo la correcta configuraci\'on del ambiente virtual utilizado para emular la m\'aquina MIPS, aunque esto fue paliado en gran parte por la documentaci\'on y explicaciones provistas por la c\'atedra. Finalmente, tambi\'en fue invertida una cantidad considerable de tiempo en aprender a utilizar e investigar sobre \LaTeX{}, ya que si bien permite obtener muy buenos resultados, se requiere de mucha lectura para poder aprovechar todo su potencial. En este sentido, el modelo de informe suministrado tambi\'en fue muy util para dar los primeros pasos.\\
Por las razones expuestas, consideramos muy necesario un trabajo pr\'actico introductorio de esta naturaleza, sin gran dificultad algor\'itmica o te\'orica pero justamente orientado a nivelar e introducir los elementos a utilizar en las dem\'as actividades pr\'acticas que se desarrollar\'an en el curso.\\
Como conclusi\'on final, podemos considerar que hemos logrado obtener un buen manejo de las herramientas introducidas en este primer proyecto.

\pagebreak

\begin{thebibliography}{99}
	
\bibitem{GXEMUL} GXemul, http://gxemul.sourceforge.net/

\bibitem{NETBSD} The NetBSD Project, http://www.netbsd.org/

\bibitem{RFC4648} RFC 4648 http://tools.ietf.org/html/rfc4648

\bibitem{LIBROC} Kernighan, Brian W. / Ritchie, Dennis M. \underline{El Lenguaje De Prorgamaci\'on C}. Segunda Edici\'on, PRENTICE-HALL HISPANOAMERICANA SA, 1991.

\bibitem{LATEX} Oetiker, Tobias, "The Not So Short Introduction To LaTeX2", http://www.physics.udel.edu/$\sim$dubois/lshort2e/

\end{thebibliography}

\end{document}
